<?php
///
namespace lxsphp\Core\Mvc;

///
use lxsphp\App;

/**
 * 框架 - 控制器类
 *
 * @version $Id: Controller.php 175 2014-07-16 10:21:58Z linsir123 $
 * @package lxsphp\Core\Mvc
 */
class Controller
{
	/**
	 * [前/后置方法](允许)
	 */
	const FILTER_ALLOW = "FILTER_ALLOW";

	/**
	 * [前/后置方法](拒绝)
	 */
	const FILTER_DENY = "FILTER_DENY";

	/**
	 * 控制器类名前缀
	 */
	const PRE_ACTION = "Action";

	/**
	 * 默认的控制器名称
	 *
	 * @var string
	 */
	public $defaultAction = 'Home';

	/**
	 * 需要执行“前/后置方法”的方法列表“*”表示全部
	 *
	 * @example array('index','client','clent2')
	 * @example '*'
	 * @var mixed
	 */
	public $filterActions = '*';

	/**
	 * [前/后置方法]的方式
	 *
	 * @var string
	 */
	public $filterType = self::FILTER_ALLOW;

	/**
	 * 控制器类名称
	 * // 首字大写 [只供子类使用]
	 *
	 * @var string
	 */
	public $controller;

	/**
	 * 控制器方法名称
	 * // 首字大写 [只供子类使用]
	 *
	 * @var string
	 */
	public $action;

	/**
	 * 前置过滤(供子类覆盖)
	 */
	public function prefixAction()
	{
	}

	/**
	 * 后置过滤(供子类覆盖)
	 */
	public function suffixAction()
	{
	}

	/**
	 * 初始化模板信息
	 *
	 * @param string $tpl 模板文件名
	 * @param string $cacheId 当开启缓存时的缓存ID
	 * @param string $suffix 模板文件后缀
	 */
	public function display($tpl, $cacheId = '', $suffix = '.html')
	{
		$tpl .= $suffix;

		///
		App::$I->getView()->display($tpl, $cacheId);
	}

	/**
	 * Smarty的assign方法
	 *
	 * @param string $name 视图层的变量名
	 * @param mixed $val 待传送到视图层的数据
	 */
	public function assign($name, $val = null)
	{
		///
		App::$I->getView()->assign($name, $val);
	}

	/**
	 * 由Dispatcher调用执行控制器方法
	 *
	 * @param string $controller 控制器名
	 * @param string $action 方法名
	 *
	 * @return array
	 */
	public function doAction($controller, $action)
	{
		///
		if (empty($action))
			$action = $this->defaultAction;

		///
		$this->controller = $controller;
		$this->action = ucfirst($action);
		$method = self::PRE_ACTION . $this->action;

		///
		if (! method_exists($this, $method))
			return array(false, "The controller::action({$method}) is miss.");

		///
		$this->_doMethod($method);

		return array(true, null);
	}

	/**
	 * 执行方法
	 *
	 * @param string $method 方法名
	 */
	private function _doMethod($method)
	{
		///
		$list = array($method);

		///
		$type = $this->filterType;
		$actions = $this->filterActions;
		$flag = $actions === '*';
		if (! $flag && is_array($actions))
			$flag = in_array($this->action, $actions);

		///
		if (($flag && $type == self::FILTER_ALLOW)
			|| (! $flag && $type == self::FILTER_DENY)
		)
			$list = array('prefixAction', $method, 'suffixAction');

		///
		foreach ($list as $v)
			call_user_func_array(array($this, $v), array());
	}
}
